<script setup>
import { onMounted } from "vue";
import * as THREE from "three";
import * as Cesium from "cesium";
import TCesium from "@/utils/TCesium.js";

let tCesium, frameBuffer;
const loader = new THREE.FileLoader();
THREE.Cache.enabled = true;
loader.setResponseType("json");
function animate() {
  tCesium.renderCesium();
  tCesium.renderThree();
  requestAnimationFrame(animate);
}
function createResources(context) {
  // 获取绘制区域的宽高
  // 非全屏时：宽1488，高704
  // 全屏时：宽1528，高858
  const width = context.drawingBufferWidth;
  const height = context.drawingBufferHeight;
  // 创建Framebuffer对象
  frameBuffer = new Cesium.Framebuffer({
    context: context,
    colorTextures: [
      new Cesium.Texture({
        context: context,
        width: width,
        height: height,
        pixelFormat: Cesium.PixelFormat.RGBA,
      }),
    ],
    depthTexture: new Cesium.Texture({
      context: context,
      width: width,
      height: height,
      pixelFormat: Cesium.PixelFormat.DEPTH_COMPONENT,
      pixelDatatype: Cesium.PixelDatatype.UNSIGNED_SHORT,
    }),
  });
}
function update(viewer, frameState) {
  let scene = viewer.scene;

  var frameState = scene._frameState;

  var context = scene.context;
  var us = context.uniformState;

  var view = scene._defaultView;
  scene._view = view;

  scene.updateFrameState();
  frameState.passes.render = true;
  frameState.passes.postProcess = scene.postProcessStages.hasSelected;

  scene.fog.update(frameState);

  us.update(frameState);

  var shadowMap = scene.shadowMap;
  if (Cesium.defined(shadowMap) && shadowMap.enabled) {
    frameState.shadowMaps.push(shadowMap);
  }

  scene._computeCommandList.length = 0;
  scene._overlayCommandList.length = 0;

  var viewport = view.viewport;
  viewport.x = 0;
  viewport.y = 0;
  viewport.width = context.drawingBufferWidth;
  viewport.height = context.drawingBufferHeight;

  var passState = view.passState;
  // passState.framebuffer = undefined;
  passState.framebuffer = frameBuffer;
  passState.blendingEnabled = undefined;
  passState.scissorTest = undefined;

  passState.viewport = Cesium.BoundingRectangle.clone(
    viewport,
    passState.viewport
  );

  // var primitives = viewer.scene.primitives;
  // primitives.update(frameState);
  if (Cesium.defined(scene.globe)) {
    scene.globe.beginFrame(frameState);
  }

  scene.updateEnvironment();
  scene.updateAndExecuteCommands(passState, scene.backgroundColor);
  scene.resolveFramebuffers(passState);

  if (Cesium.defined(scene.globe)) {
    scene.globe.endFrame(frameState);

    if (!scene.globe.tilesLoaded) {
      scene._renderRequested = true;
    }
  }
  context.endFrame();
}
onMounted(() => {
  tCesium = new TCesium("cesiumContainer", [-180, -90], [180, 90]);
  window.tCesium = tCesium;
  const viewer = tCesium.cesium.viewer;
  tCesium.cesium.viewer.scene.globe.depthTestAgainstTerrain = false;
  animate();
  setTimeout(() => {
    createResources(viewer.scene.context);
    viewer.scene.preRender.addEventListener((scene, time) => {
      update(viewer, frameBuffer);
      var cavs = document.getElementById("canvas");
      let width = viewer.scene.context.drawingBufferWidth;
      let height = viewer.scene.context.drawingBufferHeight;
      cavs.width = width;
      cavs.height = height;
      // DOM 的 <canvas>（用 getContext("2d")）不能处理 WebGLTexture，因为那是 GPU 内部的资源，不是可直接访问的图像或像素数据
      // Cesium.Texture 不能直接用于 <img> 或 <canvas> 上。你必须先将它的像素数据读出来
      const colorTexture = frameBuffer.getColorTexture(0);
      // 使用 WebGL 的 readPixels 把 GPU 里的颜色数据读回 CPU 内存
      // 必须使用 readPixels，因为不能直接将 Cesium 的 colorTexture（WebGLTexture）直接绘制到 DOM 的 <canvas> 上
      var pixels = viewer.scene.context.readPixels({
        x: 0,
        y: 0,
        width: width,
        height: height,
        framebuffer: frameBuffer,
      });
      var ctx = cavs.getContext("2d");
      let imgData = ctx.createImageData(width, height);
      // 注意：WebGL 原点在左下角，canvas2D 原点在左上角，需要垂直翻转图像
      for (let y = 0; y < height; ++y) {
        for (let x = 0; x < width; ++x) {
          const srcIndex = ((height - y - 1) * width + x) * 4; // 垂直翻转
          const dstIndex = (y * width + x) * 4;
          imgData.data[dstIndex] = pixels[srcIndex]; // R
          imgData.data[dstIndex + 1] = pixels[srcIndex + 1]; // G
          imgData.data[dstIndex + 2] = pixels[srcIndex + 2]; // B
          imgData.data[dstIndex + 3] = pixels[srcIndex + 3]; // A
        }
      }
      ctx.putImageData(imgData, 0, 0, 0, 0, width, height);
    });
  }, 2000);
});
</script>

<template>
  <div id="cesiumContainer">
    <canvas
      id="canvas"
      style="
        width: 30%;
        position: absolute;
        z-index: 2;
        top: 50px;
        left: 50px;
        background-color: red;
        border: 1px solid #000;
      "
    ></canvas>
  </div>
</template>

<style lang="scss">
#cesiumContainer {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  position: absolute;
  top: 0;
  left: 0;
}
</style>
